package com.ideaaedi.springcloud.jd.commonspring.oauth2;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ideaaedi.springcloud.jd.commonds.constant.BaseConstant;
import com.ideaaedi.springcloud.jd.commonds.entity.BaseCodeMsgEnum;
import com.ideaaedi.springcloud.jd.commonds.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 认证端点处理器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.1.A
 */
@Slf4j
public class CustomAuthExceptionEntryPoint implements AuthenticationEntryPoint {
    
    @SuppressWarnings("deprecation")
    private final WebResponseExceptionTranslator<?> exceptionTranslator = new DefaultWebResponseExceptionTranslator();
    
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) {
        // 解析参数
        ResponseEntity<?> currResponseEntity = null;
        try {
            currResponseEntity = exceptionTranslator.translate(authException);
            log.info("currResponseEntity -> {}", currResponseEntity);
        } catch (Exception e) {
            log.warn("parse currResponseEntity error. e.getMessage() -> {}", e.getMessage());
        }
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        // response.setStatus值不要设置为HttpStatus
        response.setStatus(HttpStatus.OK.value());
        if (currResponseEntity != null && currResponseEntity.getStatusCode() == HttpStatus.UNAUTHORIZED) {
            Result<?> result = Result.failure(BaseCodeMsgEnum.INVALID_TOKEN);
            try {
                String header = request.getHeader(BaseConstant.JWT_TOKEN_KEY);
                if (StringUtils.isBlank(header) || !header.startsWith(BaseConstant.JWT_TOKEN_PREFIX)) {
                    log.debug("curr header is {}", header);
                    result = Result.failure(BaseCodeMsgEnum.MISS_JWT_TOKEN);
                }
                log.error("authe -> {}. authException.getMessage() -> {}. case1 return result -> {} ",
                        request.getRequestURI(), authException.getMessage(), result);
                response.getWriter().write(new ObjectMapper().writeValueAsString(result));
            } catch (IOException e) {
                log.error("authe fail and return data fail. e.getMessage() -> {}", e.getMessage(), authException);
            }
        } else {
            Result<?> result = Result.failure(BaseCodeMsgEnum.AUTH_FAIL);
            try {
                log.error("authe for {}. case2 return result -> {} ", request.getRequestURI(), result, authException);
                response.getWriter().write(new ObjectMapper().writeValueAsString(result));
            } catch (IOException e) {
                log.error("authe fail and return data fail. e.getMessage() -》 {}", e.getMessage(), authException);
            }
        }
    }
}
